﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace NSJL.Framework.Utils
{
    public class SelfUtil
    {
        public static void Open()
        {
            VirtualKeyboardHelper.ShowVirtualKeyboard();


            //var tabTipFile = @"C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe";
            //if (!System.IO.File.Exists(tabTipFile))
            //{
            //    tabTipFile = Environment.CurrentDirectory + @"\TabTip.exe";
            //}
            //if (System.IO.File.Exists(tabTipFile))
            //{
            //    Process.Start(tabTipFile);
            //    return;
            //}
            //var oskFilePath = Environment.CurrentDirectory + @"\osk.exe";
            //if (System.IO.File.Exists(oskFilePath))
            //{
            //    var proc = new Process();
            //    proc.StartInfo.FileName = oskFilePath;
            //    proc.StartInfo.UseShellExecute = true;
            //    proc.StartInfo.Verb = "runas";
            //    proc.Start();
            //}
        }
        public static int DefaultPageSize = 20;
        public static string GetGUID()
        {
            return Guid.NewGuid().ToString("N");
        }
        public static byte[] HMACSHA1Text(string text, string key)
        {
            HMACSHA1 hmacsha1 = new HMACSHA1();
            hmacsha1.Key = System.Text.Encoding.UTF8.GetBytes(key);
            byte[] dataBuffer = System.Text.Encoding.UTF8.GetBytes(text);
            byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
            return hashBytes;
        }
        public static string CharCodeAt(string inpString, int index)
        {
            string outString = "";
            for (var i = 0; i < inpString.Length; i++)
            {
                if (i == index)
                {
                    outString = ((int)inpString[i]).ToString();
                    break;
                }
            }
            return outString;
        }
        public static byte[] StrToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
        public static string MD5Encrypt(string password, int bit)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] hashedDataBytes;
            hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(password));
            StringBuilder tmp = new StringBuilder();
            foreach (byte i in hashedDataBytes)
            {
                tmp.Append(i.ToString("x2"));
            }
            if (bit == 16)
                return tmp.ToString().Substring(8, 16);
            else
            if (bit == 32) return tmp.ToString();//默认情况
            else return string.Empty;
        }
        public static string GetIPFromHttpXForwardedFor()
        {
            HttpRequest request = HttpContext.Current.Request;
            string result = request.Headers["X-Forwarded-For"];
            if (!string.IsNullOrEmpty(result))
            {
                int index = result.IndexOf(".", StringComparison.Ordinal);
                //可能有代理   
                if (index == -1)//没有"."肯定是非IPv4格式   
                {
                    if (!IsIP(result))//代理不是IP格式
                    {
                        result = null;
                    }
                }
                else
                {
                    //有","，估计多个代理。取第一个不是内网的IP。   
                    result = result.Replace(" ", "").Replace("\"", "");
                    string[] tempIps = result.Split(",;".ToCharArray());
                    foreach (string temp in tempIps)
                    {
                        if (IsIP(temp)
                            && temp.Substring(0, 3) != "10."
                            && temp.Substring(0, 7) != "192.168"
                            && temp.Substring(0, 7) != "172.16.")
                        {
                            return temp;//找到不是内网的地址   
                        }
                    }
                }
            }
            if (string.IsNullOrEmpty(result))
            {
                result = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = request.UserHostAddress;
            }
            if (result == "::1")
            {
                result = "127.0.0.1";
            }
            return result;
        }
        public static string GetMD5(string fileurl)
        {
            try
            {
                FileStream file = new FileStream(fileurl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                MD5 md5 = new MD5CryptoServiceProvider();
                var retval = md5.ComputeHash(file);
                file.Close();
                StringBuilder sc = new StringBuilder();
                for (int i = 0; i < retval.Length; i++)
                {
                    sc.Append(retval[i].ToString("x2"));
                }
                return sc.ToString();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return "";
        }
        public static string ConvertJson(string json)
        {
            json = Regex.Replace(json, @"\\/Date\((\d+)\)\\/", match =>
            {
                DateTime dt = new DateTime(1970, 1, 1);
                dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
                dt = dt.ToLocalTime();
                return dt.ToString("yyyy-MM-dd HH:mm:ss");
            });
            json = Regex.Replace(json, @"null", match =>
            {
                return "\"\"";
            });
            return json;
        }
        public static string GetHostAddress()
        {
            string userHostAddress = HttpContext.Current.Request.UserHostAddress;

            if (string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }

            //最后判断获取是否成功，并检查IP地址的格式（检查其格式非常重要）
            if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
            {
                return userHostAddress;
            }
            return "127.0.0.1";
        }
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }
        public static string GetTimeStamp(int flag = 0)
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            if (flag == 0)
            {
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }
        public static string GetShortUrl(string url)
        {
            url = HttpUtility.UrlEncode(url);
            var temp = GetRequest("http://api.t.sina.com.cn/short_url/shorten.json?source=2815391962&url_long=" + url);
            var model = new JavaScriptSerializer().Deserialize<List<ShortUrl>>(temp);
            var info = model.FirstOrDefault();
            if (info == null)
            {
                return "";
            }
            return info.url_short;
        }
        public class ShortUrl
        {
            public string url_short { get; set; }
            public string url_long { get; set; }
        }
        public static string GetRequest(string url, string data = "", string cookie = "",string referer="",string ua="")
        {
            try
            {
                //ServicePointManager.Expect100Continue = false;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

                string strBuff = "";
                Uri httpURL = new Uri(url);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpURL);
                
                if (!string.IsNullOrWhiteSpace(ua))
                {
                    request.UserAgent = ua;
                }
                else
                {
                    request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3719.400 QQBrowser/10.5.3715.400";
                }
                request.Accept = "*/*";
                if (!string.IsNullOrWhiteSpace(cookie))
                {
                    request.Headers.Add("Cookie", cookie);
                }
                if (!string.IsNullOrWhiteSpace(referer))
                {
                    request.Referer = referer;
                }
                if (!string.IsNullOrWhiteSpace(data))
                {
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
                    byte[] postdata = System.Text.Encoding.UTF8.GetBytes(data);
                    request.ContentLength = postdata.Length;
                    Stream newStream = request.GetRequestStream();
                    newStream.Write(postdata, 0, postdata.Length);
                    newStream.Close();
                }
                HttpWebResponse httpResp = (HttpWebResponse)request.GetResponse();
                Stream respStream = httpResp.GetResponseStream();
                StreamReader respStreamReader = new StreamReader(respStream, Encoding.UTF8);
                strBuff = respStreamReader.ReadToEnd();
                request.Abort();
                httpResp.Close();
                if (respStream != null)
                {
                    respStream.Close();
                }
                respStreamReader.Close();
                return strBuff;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public static string ChooseSaveFile()
        {
            SaveFileDialog dialog = new SaveFileDialog();
            //dialog.Multiselect = false;//该值确定是否可以选择多个文件
            dialog.FileName = string.Format("{0}.xls", DateTime.Now.ToString("yyyyMMddHHmm"));
            dialog.Title = "请选择文件夹";
            dialog.Filter = "Execl files (*.xls)|*.xls";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                return dialog.FileName;
            }
            return null;
        }
        public static string ChooseFile()
        {
            System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
            //dialog.Multiselect = false;//该值确定是否可以选择多个文件
            dialog.Title = "请选择文件夹";
            dialog.Filter = "所有文件(*.*)|*.*";
            dialog.InitialDirectory = "D:\\桌面\\DCC智能柜";
            //dialog.ShowNewFolderButton = false;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                return dialog.FileName;
            }
            return null;
        }
        
        public static string ChooseFileTest()
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.Description = "请选择一个文件夹";
            folderBrowserDialog.ShowNewFolderButton = false;
            folderBrowserDialog.SelectedPath = "D:\\桌面\\DCC智能柜"; // 设置初始目录为当前目录或特定目录

            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                string folderPath = folderBrowserDialog.SelectedPath;
                // 然后你可以在这个文件夹内使用OpenFileDialog
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.InitialDirectory = folderPath;
                openFileDialog.Filter = "所有文件(*.*)|*.*";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 处理文件选择逻辑
                    return openFileDialog.FileName;
                }

            }
            return null;
        }
        public static DataTable ListToDataTable<T>(List<T> list)
        {
            //创建一个名为"tableName"的空表
            DataTable dt = new DataTable("tableName");

            //创建传入对象名称的列
            foreach (var item in list.FirstOrDefault().GetType().GetProperties())
            {
                dt.Columns.Add(item.Name);
            }

            //循环存储
            foreach (var item in list)
            {
                //新加行
                DataRow value = dt.NewRow();
                //根据DataTable中的值，进行对应的赋值
                foreach (DataColumn dtColumn in dt.Columns)
                {
                    int i = dt.Columns.IndexOf(dtColumn);
                    //基元元素，直接复制，对象类型等，进行序列化
                    if (value.GetType().IsPrimitive)
                    {
                        value[i] = item.GetType().GetProperty(dtColumn.ColumnName).GetValue(item);
                    }
                    else
                    {
                        var dataValue = item.GetType().GetProperty(dtColumn.ColumnName).GetValue(item);
                        var temp = JsonConvert.SerializeObject(dataValue).Replace("\"", "");
                        if (temp == "null")
                        {
                            temp = "";
                        }
                        if (dataValue==null||dataValue.GetType() == typeof(DateTime) || dataValue.GetType() == typeof(DateTime?))
                        {
                            if (dataValue == null)
                            {
                                temp = "";
                            }
                            else
                            {
                                temp = ((DateTime) dataValue).ToString("yyyy-MM-dd HH:mm:ss");
                            }
                        }
                        value[i] = temp;
                    }
                }
                dt.Rows.Add(value);
            }
            return dt;

        }
        public static string ReplaceStrNum(string str)
        {
            str = str.Replace("０", "0").Replace("１", "1").Replace("２", "2").Replace("３", "3").Replace("４", "4").Replace("５", "5").Replace("６", "6").Replace("７", "7").Replace("８", "8").Replace("９", "9");
            return str;
        }
        //箱门串口协议校验
        public static byte XorCheck(byte[] strbuff)
        {
            int num1 = 0;
            for (int i = 0; i < strbuff.Length; i++)
            {
                num1 = num1 ^ strbuff[i];
            }
            return (byte)num1;
        }
        public static T Deserialize<T>(string xml)
        {
            using (StringReader sr = new StringReader(xml))
            {
                XmlSerializer xmldes = new XmlSerializer(typeof(T));
                return (T)xmldes.Deserialize(sr);
            }

        }
        public static T GetXmlWithPath<T>(string path = "config/DJCabinetCfg.xml")
            where T : class
        {
            try
            {
                var info = SelfUtil.Deserialize<T>(File.ReadAllText(path));
                return info;
            }
            catch (Exception e)
            {
                return null;
            }
        }


        //获取CPU序列号
        public static string GetCPUSerialNumber()
        {
            //return "BFEBFBFF000906EA";
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Processor");
                string sCPUSerialNumber = "";
                foreach (ManagementObject mo in searcher.Get())
                {
                    sCPUSerialNumber = mo["ProcessorId"].ToString().Trim();
                    break;
                }
                return sCPUSerialNumber;
            }
            catch
            {
                return "";
            }
        }


        //获取主板序列号
        public static string GetBIOSSerialNumber()
        {
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_BIOS");
                string sBIOSSerialNumber = "";
                foreach (ManagementObject mo in searcher.Get())
                {
                    sBIOSSerialNumber = mo.GetPropertyValue("SerialNumber").ToString().Trim();
                    break;
                }
                return sBIOSSerialNumber;
            }
            catch
            {
                return "";
            }
        }


        //获取硬盘序列号
        public static string GetHardDiskSerialNumber()
        {
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
                string sHardDiskSerialNumber = "";
                foreach (ManagementObject mo in searcher.Get())
                {
                    sHardDiskSerialNumber = mo["SerialNumber"].ToString().Trim();
                    break;
                }
                return sHardDiskSerialNumber;
            }
            catch
            {
                return "";
            }
        }
    }
}
